home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 April
/
EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso
/
EARCD
/
gfx
/
board
/
rtgmv13.lha
/
devdocs
/
tcpsrc.c
< prev
Wrap
C/C++ Source or Header
|
1996-06-27
|
7KB
|
289 lines
/*
This is the source code of the TCP/IP Support stuff
of rtgmaster.library... originally it was included,
as in rtgmaster.library V5 TCP/IP Support had to
contain a LOT of Forbid()/Permit() calls, that slowed
the thing down. (This was only needed for AmiTCP stuff
inside a Shared Library). In the meanwhile, i got
a reply from the coders of AmiTCP how to do this
inside a shared library without a single Forbid()/Permit()
call... so you could call this source obsolete...
if you want to know how TCP/IP works NATIVE, you
still can have a look at it :) Of course this source
is only usable from C, while the rtgmaster stuff is
usable from ASM, too... i hope i did not forget
any includes for the source version...
THIS STUFF IS OBSOLETE, AS THE PROBLEMS THAT I HAD
WITH TCP/IP SUPPORT AT THE BEGINNING, DISAPPEARED...
IT IS THE CODE OF rtgmaster.library V6, AND DOES
NOT SUPPORT UDP, CONTRARY TO rtgmaster.library V7 !!!
*/
// NOTE : Function Parameters are nearly the same, only
// that you have to provide a struct Library *SocketBase,
// and have to call SocketBase=OpenLibrary("bsdsocket.library",4);
// instead of providing SocketBase as parameters...
// Urgent note : If you want to use this code from different
// TASKS, provide the SocketBase as additional parameter "SBase" and
// give each function a local variable
// struct Library *SocketBase=SBase;
// Else you will get a LOT of AmiTCP error messages (this is the
// "famous" rtgmaster V6 speedfix. At the beginning i had a
// Forbid();/* Global */ SocketBase=SBase;Permit(); which
// of course is much slower than the local variable stuff...
#include <sys/types.h>
#include <exec/nodes.h>
#include <clib/socket_protos.h>
#include <pragmas/socket_pragmas.h>
#include <clib/netlib_protos.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <rtgmaster/rtgTCPIP.h>
#include <stdlib.h>
#include <stdio.h>
#include <clib/alib_protos.h>
#include <exec/memory.h>
#include <string.h>
#include <ctype.h>
// Note : Some of these includes might ACTUALLY
// be not needed... i hope i forgot no include :)
#define CREATE(result, type, number) do {\
if (!((result) = (type *) calloc ((number), sizeof(type))))\
result=0;} while(0);
struct RTG_Socket *OpenServer(int port, int mode, int protocol)
{
int opt,s;
long handle;
struct sockaddr_in sa;
static struct RTG_Socket rs;
if ((s=socket(AF_INET,mode,protocol))<0) return(0);
#if defined(SO_SNDBUF)
opt = (LARGE_BUFSIZE + GARBAGE_SPACE);
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &opt, sizeof(opt)) < 0) return(0);
#endif
#if defined(SO_REUSEADDR)
opt = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)) < 0) return(0);
#endif
#if defined(SO_LINGER)
{
struct linger ld;
ld.l_onoff = 0;
ld.l_linger = 0;
if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &ld, sizeof(ld)) < 0) return(0);
}
#endif
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
{
CloseSocket(s);
return(0);
}
listen(s,5);
rs.s=s;
rs.num=1;
rs.list=0;
FD_ZERO(&(rs.input_set));
FD_ZERO(&(rs.output_set));
FD_ZERO(&(rs.exc_set));
return(&rs);
}
void makeservaddr(struct sockaddr_in *address, char *host, int port);
void makeservaddr(struct sockaddr_in *address, char *host, int port)
{
struct hostent *hi;
address->sin_family=AF_INET;
hi=gethostbyname(host);
bcopy(hi->h_addr,&address->sin_addr,hi->h_length);
address->sin_port=port;
}
struct RTG_Socket *OpenClient(char *host, int port, int mode, int protocol)
{
struct sockaddr_in sa;
struct sockaddr_in *sb;
struct hostent *hi;
long handle;
static struct RTG_Socket rs;
int s;
if ((s=socket(AF_INET,mode,protocol))<0) return(0);
makeservaddr(&sa,host,port);
if (connect(s,&sa,sizeof(sa))<0) return(0);
rs.s=s;
rs.num=1;
rs.list=0;
return(&rs);
}
struct RTG_Socket *RunServer(struct RTG_Socket *s, struct RTG_Buff *in_buffer, struct RTG_Buff *out_buffer, int maxplayers)
{
int maxdesc;
int num=0;
struct timeval null_time;
struct RTG_Socket *d;
int socknum=0;
struct RTG_Socket *new_conn=0;
if (maxplayers>12) maxplayers=12;
null_time.tv_sec=0;
null_time.tv_usec=0;
if (s->list==0)
{
FD_ZERO(&(s->input_set));
FD_SET(s->s,&(s->input_set));
if (WaitSelect((s->s)+1, &(s->input_set), (fd_set *) 0, (fd_set *) 0, NULL,0) >= 0)
{
// New connection...
}
}
FD_ZERO(&(s->input_set));
FD_ZERO(&(s->output_set));
FD_ZERO(&(s->exc_set));
FD_SET(s->s,&(s->input_set));
maxdesc=s->s;
if (s->list!=0) for (d=s->list;d;d=d->list)
{
if ((d->s)>maxdesc) maxdesc=d->s;
FD_SET(d->s,&(s->input_set));
FD_SET(d->s,&(s->output_set));
FD_SET(d->s,&(s->exc_set));
}
if (WaitSelect(maxdesc+1,&(s->input_set),&(s->output_set),&(s->exc_set),&null_time,0) >= 0)
{
// We have input...
}
if (FD_ISSET(s->s,&(s->input_set)))
{
// Allocate new descriptor
int i;
struct sockaddr_in peer;
int desc;
if ((desc = accept(s->s, 0,0))==-1)
{
return(0);
}
else
{
for (d=s->list;d;d=d->list)
socknum++;
if (socknum>=maxplayers)
{
CloseSocket(desc);
return(0);
}
if (s->list!=0) for(d=s->list;(d->list);d=d->list);
else d=s;
if (s->num==maxplayers) return(0);
CREATE(d->list,struct RTG_Socket,1);
if ((d->list)==0) return(0);
d=d->list;
d->s=desc;
d->num=1;
d->list=0;
new_conn=d;
s->num++;
}
}
if (s->list!=0) for (d=s->list;d;d=d->list)
{
if (FD_ISSET(d->s,&(s->exc_set)))
{
FD_CLR(d->s,&(s->input_set));
FD_CLR(d->s,&(s->output_set));
CloseSocket(d->s);
}
}
if (s->list!=0) for (d=s->list;d;d=d->list)
{
if (FD_ISSET(d->s,&(s->input_set)))
{
int state;
state=recv(d->s,in_buffer->sock[num],in_buffer->in_size,0);
in_buffer->num[num]=d->s;
num++;
if (state<0) {num--;CloseSocket(d->s);in_buffer->num[num]=-1;}
//Handle input, if it fails, CloseSocket !!!
}
}
if (s->list!=0) for (d=s->list;d;d=d->list)
{
if (FD_ISSET(d->s,&(s->output_set)))
{
int state,f,g;
g=-1;
for (f=0;((f<maxplayers)&&(g==-1));f++)
if (out_buffer->num[f]==d->s) g=f;
state=send(d->s,&(out_buffer->sock[g]),out_buffer->out_size,0);
if (state<0) CloseSocket(d->s);
// Handle output, if it fails, CloseSocket !!!
}
}
return(new_conn);
}
void CloseServer(struct RTG_Socket *s)
{
if (s->s) CloseSocket(s->s);
s->s=0;
}
void CloseClient(struct RTG_Socket *s)
{
if (s->s) CloseSocket(s->s);
s->s=0;
}
int RtgSend(struct RTG_Socket *s, char *message, int len)
{
int test;
test=(send(s->s,message,len,0));
return(test);
}
int RtgRecv(struct RTG_Socket *s, char *message, int len)
{
int test;
test=(recv(s->s,message,len,0));
return(test);
}
struct RTG_Socket *RtgAccept(struct RTG_Socket *s)
{
static struct RTG_Socket rs;
rs.s=accept(s->s,0,0);
if (rs.s>=0)
{
rs.num=1;
rs.list=0;
return(&rs);
}
else return(0);
}
int RtgIoctl(struct RTG_Socket *s, long *arg)
{
int test;
test=(IoctlSocket(s->s,FIONBIO,arg));
return(test);
}